package system

import (
	"ruoyi_gin/app/admin/model/tools"
	"ruoyi_gin/utils"
	"ruoyi_gin/utils/R"
	"time"
)

// SysPost model：数据库字段
type SysPost struct {
	PostId     int       `json:"postId" gorm:"column:post_id;primaryKey"` //表示主键
	PostCode   string    `json:"postCode" gorm:"post_code"`
	PostName   string    `json:"postName" gorm:"post_name"`
	PostSort   int       `json:"postSort" gorm:"post_sort"`
	Status     string    `json:"status" gorm:"status"`
	CreateBy   string    `json:"createBy" gorm:"create_by"`
	CreateTime time.Time `json:"createTime" gorm:"column:create_time;type:datetime"`
	UpdateBy   string    `json:"updateBy" gorm:"update_by"`
	UpdateTime time.Time `json:"updateTime" gorm:"column:update_time;type:datetime"`
	Remark     string    `json:"remark" gorm:"remark"`
}

type SysRolesParam struct {
	RoleId            int       `json:"roleId" gorm:"column:role_id;primaryKey"` //表示主键
	RoleName          string    `json:"roleName" gorm:"role_name"`
	RoleKey           string    `json:"roleKey" gorm:"role_key"`
	RoleSort          int       `json:"roleSort" gorm:"role_sort"`
	DataScope         string    `json:"dataScope" gorm:"data_scope"`
	Status            string    `json:"status" gorm:"status"`
	MenuCheckStrictly bool      `json:"menuCheckStrictly" gorm:"menu_check_strictly"`
	DeptCheckStrictly bool      `json:"deptCheckStrictly" gorm:"dept_check_strictly"`
	DelFlag           string    `json:"delFlag" gorm:"del_flag"`
	CreateBy          string    `json:"createBy" gorm:"create_by"`
	CreateTime        time.Time `json:"createTime" gorm:"column:create_time;type:datetime"`
	UpdateBy          string    `json:"updateBy" gorm:"update_by"`
	UpdateTime        time.Time `json:"updateTime" gorm:"column:update_time;type:datetime"`
	Remark            string    `json:"remark" gorm:"remark"`
	MenuIds           []int     `json:"menuIds"`
	DeptIds           []int     `json:"deptIds"`
}

// TableName 指定数据库表名称
func (SysPost) TableName() string {
	return "sys_post"
}

func SaveRole(roles SysRolesParam) R.Result {

	roleName := roles.RoleName

	role := checkRoleNameUnique(roleName)

	if role.RoleId != 0 {
		return R.ReturnFailMsg("新增角色'" + role.RoleName + "'失败，角色名称已存在")
	}
	roleKey := role.RoleKey

	role = checkRoleKeyUnique(roleKey)

	if role.RoleId != 0 {

		return R.ReturnFailMsg("新增角色'" + role.RoleName + "'失败，角色权限已存在")
	}
	role.DataScope = "2"
	role.DelFlag = "0"

	err := utils.MysqlDb.Model(&SysRoles{}).Create(roles).Error

	if err != nil {
		return R.ReturnFailMsg(err.Error())
	}

	insertRoleMenu(roles)

	return R.ReturnSuccess("操作成功")
}

func insertRoleMenu(roles SysRolesParam) {

	menuIds := roles.MenuIds

	var roleMenu []SysRoleMenu

	for i := 0; i < len(menuIds); i++ {
		menuId := menuIds[i]
		roleId := roles.RoleId
		roleMenu = append(roleMenu, SysRoleMenu{RoleId: roleId, MenuId: menuId})
	}

	err := utils.MysqlDb.Model(&SysRoleMenu{}).Create(&roleMenu).Error

	if err != nil {
		panic(R.ReturnFailMsg(err.Error()))
	}
}

func checkRoleKeyUnique(roleKey string) SysRoles {

	var role SysRoles

	var sql = baseSql + "where r.role_key = '" + roleKey + "' and r.del_flag = '0' limit 1"

	err := utils.MysqlDb.Raw(sql).Scan(&role).Error

	if err != nil {

		panic(R.ReturnFailMsg(err.Error()))
	}

	return role
}

func checkRoleNameUnique(roleName string) SysRoles {

	var role SysRoles

	var sql = baseSql + "where r.role_name = '" + roleName + "' and r.del_flag = '0' limit 1"

	err := utils.MysqlDb.Raw(sql).Scan(&role).Error

	if err != nil {

		panic(R.ReturnFailMsg(err.Error()))
	}

	return role
}

func SelectUserPostGroup(userName string) string {

	var posts []SysPost

	var result = ""

	utils.MysqlDb.Raw("select p.post_id, p.post_name, p.post_code "+
		"from sys_post p "+
		"left join sys_user_post up on up.post_id = p.post_id "+
		"left join sys_user u on u.user_id = up.user_id "+
		"where u.user_name = ?", userName).Scan(&posts)

	if posts != nil {
		for i := range posts {
			sysPost := posts[i]
			if i == 0 {
				result = sysPost.PostName
			} else {
				result += "," + sysPost.PostName
			}
		}
	}
	return result
}

// 分页查询
func SelectSysPostList(params tools.SearchTableDataParam, isPage bool) tools.TableDataInfo {

	var pageNum = params.PageNum
	var pageSize = params.PageSize
	sysPost := params.Other.(SysPost)

	offset := (pageNum - 1) * pageSize
	var total int64
	var rows []SysPost

	var db = utils.MysqlDb.Model(&rows)

	var postCode = sysPost.PostCode
	if postCode != "" {
		db.Where("post_code like ?", "%"+postCode+"%")
	}
	var status = sysPost.Status
	if status != "" {
		db.Where("status = ?", status)
	}
	var postName = sysPost.PostName
	if postName != "" {
		db.Where("post_name like ?", "%"+postName+"%")
	}

	db.Order("post_sort")

	if err := db.Count(&total).Error; err != nil {
		return tools.Fail()
	}
	if isPage {
		if err := db.Limit(pageSize).Offset(offset).Find(&rows).Error; err != nil {
			return tools.Fail()
		}
	} else {
		if err := db.Find(&rows).Error; err != nil {
			return tools.Fail()
		}
	}

	if rows == nil {
		return tools.Fail()
	} else {
		return tools.Success(rows, total)
	}
}
